package com.qcu.websocket;


import com.alibaba.fastjson2.JSON;
import com.qcu.websocket.pojo.Message;
import com.qcu.websocket.pojo.ResultMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint("/chat/{username}")
@Component
@Slf4j
public class ChatEndpoint {

    // 保存在线的用户，key为用户名，value为 Session 对象
    private static final Map<String, Session> onlineUsers = new ConcurrentHashMap<>();

    private static final Map<String, Session> onlinePlains = new ConcurrentHashMap<>();

    // 随机获取plain
    public Map<String,Session> getRandomSession() {
        Map<String,Session> map = new HashMap<>();
        List<String> keys = new ArrayList<>(onlinePlains.keySet());
        if (keys.isEmpty()) {
            return null;
        }
        Random random = new Random();
        String randomKey = keys.get(random.nextInt(keys.size()));
        map.put(randomKey, onlinePlains.get(randomKey));
        return map;
    }
    // 当前用户的session
    private Session session;
    // 当前用户名
    private String username;

    /**
     * 建立websocket连接后，被调用
     *
     * @param session Session
     */
    @OnOpen
    public void onOpen(@PathParam("username") String username, Session session) {
        log.info("{}:获取连接",username);
        this.username = username;
        this.session = session;
        // username 如果包含 “plain” 则表示是plain，放入onlinePlains中
        if (username.contains("plain"))
            onlinePlains.put(username, session);
        else{
            // 否则放入onlineUsers中 表示普通用户
            onlineUsers.put(username, session);
            // 随机分配一个 plain
            Map<String, Session> randomPlain = getRandomSession();
            // 获取随机的plain
            Session plainSession = null;
            // 发送随机plain的username给普通用户
            if (randomPlain.size() != 0) {
                ResultMessage resultMessage = new ResultMessage();
                Set<Map.Entry<String, Session>> entries = randomPlain.entrySet();
                String plainName = null;
                for (Map.Entry<String, Session> entry : entries) {
                    plainName = entry.getKey();
                    plainSession = entry.getValue();
                }
                resultMessage.setSystem(true);
                resultMessage.setFromName(null);
                // 是plain
                resultMessage.setPlain(true);
                // 是未读消息
                resultMessage.setUnread(true);
                // 将plain名字发送给普通用户，一个用户只能与一个plain聊天
                resultMessage.setMessage(plainName);
                String s = JSON.toJSONString(resultMessage);
                this.session.getAsyncRemote().sendText(s);
            }
            // 将咨询的用户名发给plain
            if (plainSession != null) {
                ResultMessage resultMessage = new ResultMessage();
                resultMessage.setSystem(true);
                resultMessage.setFromName(null);
                resultMessage.setPlain(false);
                resultMessage.setUnread(true);
                // 将咨询的用户名发给plain，一个plain可以与多个用户聊天
                resultMessage.setMessage(this.username);
                String s = JSON.toJSONString(resultMessage);
                plainSession.getAsyncRemote().sendText(s);
            }
        }
    }

    @OnMessage
    public void onMessage(String message) {
        ResultMessage resultMessage = new ResultMessage();
        Message from = JSON.parseObject(message, Message.class);
        Session toSession = null;
        // 如果发消息的是普通用户（其实前两个条件可以忽略）
        if (from.getToName() == null || from.getMessage().equals("") || from.getToName().contains("plain")){
            Map<String, Session> randomSession = getRandomSession();
            toSession = randomSession.get(from.getToName());
            resultMessage.setPlain(false);
            resultMessage.setUnread(true);
        }else {
            toSession = onlineUsers.get(from.getToName());
            resultMessage.setPlain(true);
            resultMessage.setUnread(true);
        }
        String toName = from.getToName();
        String toMsg = from.getMessage();
        log.info("用户 {} 向用户 {} 发送了 {}",username,toName,toMsg);
        resultMessage.setFromName(username);
        if (toSession != null){
            resultMessage.setMessage(toMsg);
            resultMessage.setSystem(false);
            String s = JSON.toJSONString(resultMessage);
            toSession.getAsyncRemote().sendText(s);
        }else {
            resultMessage.setMessage("暂无工作人员在线");
            resultMessage.setSystem(false);
            String s = JSON.toJSONString(resultMessage);
            onlineUsers.get(username).getAsyncRemote().sendText(s);
        }
    }
    @OnClose
    public void onClose(Session session) {
//        Message from = JSON.parseObject(message, Message.class);
//        if (username.contains("plain")){
////            onlineUsers.remove(from.getToName());
//        }else {
//            onlineUsers.remove(username);
//        }
//        log.info("{}:断开连接",username);
    }


    // 获取所有用户，暂时没用
    private Set<String> getFriends() {
        return onlineUsers.keySet();
    }
    // 广播给所有在线用户，暂时没用
    private void broadcastAllUsers(String message) {
        try {
            Set<Map.Entry<String, Session>> entries = onlineUsers.entrySet();

            for (Map.Entry<String, Session> entry : entries) {
                // 获取到所有用户对应的 session 对象
                Session session = entry.getValue();

                // 使用 getBasicRemote() 方法发送同步消息
                session.getBasicRemote().sendText(message);
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }

}
